package com.sample.rx3;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.loyal.client.RxClient;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

public class SocketActivity extends AppCompatActivity {
    private WebSocket mWebSocket;
    private final Handler heartHandler = new Handler();
    private final OkHttpClient.Builder ctBuilder = RxClient.getInstance().getOkCtBuilder();
    private static final String HEART_JSON = "{\"type\":\"quote\"}";
    private long currentTime = 0L;
    public static final long HEART_BEAT_RATE = 10 * 1000;

    private final Runnable heartCheck = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - currentTime >= HEART_BEAT_RATE) {
                //发送心跳包
                if (null != mWebSocket)
                    mWebSocket.send(HEART_JSON);
                currentTime = System.currentTimeMillis();
            }
            heartHandler.postDelayed(this, HEART_BEAT_RATE); //每隔一定的时间，对长连接进行一次心跳检测
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_socket);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        heartHandler.postDelayed(heartCheck, HEART_BEAT_RATE);
        connectSocket();
    }

    private void connectSocket() {
        //建立连接
        String serverIp = "服务器访问IP或地址";
        String serial = "设备序列号或唯一标识符";
        String wsUrl = "ws://" + serverIp + "/tracall/websocket/socketServer.do?sbxlh=" + serial;
        Request request = new Request.Builder().url(wsUrl).build();
        ctBuilder.build().newWebSocket(request, createListener());
        //mWebSocket
    }

    /**
     * 重写了WebSocketListener中的几个方法，这几个方法很好理解，是用来异步回调的，
     * 这里简单说一下：onOpen当WebSocket和远程建立连接时回调；两个onMessage就是接收到消息时回调，
     * 只是消息内容的类型不同；onClosing是当远程端暗示没有数据交互时回调（即此时准备关闭，但连接还没有关闭）；
     * onClosed就是当连接已经释放的时候被回调；onFailure当然是失败时被回调（包括连接失败，发送失败等）。
     * <p>
     * send用来发送消息；close用来关闭连接
     */
    private WebSocketListener createListener() {
        return new WebSocketListener() {
            @Override
            public void onOpen(@NonNull WebSocket webSocket, @NonNull Response response) {
                super.onOpen(webSocket, response);
                log("onOpen:", response.toString());
                mWebSocket = webSocket;
                webSocket.send(HEART_JSON);
            }

            @Override
            public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) {
                super.onMessage(webSocket, text);
                log("onMessage", text);
                runOnUiThread(() -> call(text));
            }

            @Override
            public void onClosing(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
                super.onClosing(webSocket, code, reason);
                log("onClosing", code + ":" + reason);
            }

            @Override
            public void onClosed(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
                super.onClosed(webSocket, code, reason);
                log("onClosed", code + ":" + reason);
            }

            @Override
            public void onFailure(@NonNull WebSocket webSocket, @NonNull Throwable t, Response response) {
                super.onFailure(webSocket, t, response);
                log("onFailure");
                try {
                    webSocket.close(1000, null);
                    heartHandler.postDelayed(() -> connectSocket(), 5000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }

    private void log(String message) {
        Log.e(getClass().getName(), message);
    }

    private void log(String tag, String message) {
        Log.e(getClass().getName(), tag + "->" + message);
    }

    //数据处理-要在主线程处理View
    private void call(String text) {
        runOnUiThread(() -> {

        });
    }
}
